package cn.hacynn.nd.service.impl;

import cn.hacynn.nd.common.constant.MessageConstant;
import cn.hacynn.nd.common.context.BaseContext;
import cn.hacynn.nd.common.exception.TaskException;
import cn.hacynn.nd.common.utils.OSSUtil;
import cn.hacynn.nd.mapper.TaskMapper;
import cn.hacynn.nd.mapper.UserMapper;
import cn.hacynn.nd.pojo.dto.TaskDTO;
import cn.hacynn.nd.pojo.entity.Task;
import cn.hacynn.nd.pojo.entity.User;
import cn.hacynn.nd.pojo.vo.FinishedTaskVO;
import cn.hacynn.nd.service.TaskService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * @Author Hacynn
 * @Date 2024/5/26 13:04
 * @Version 1.0
 */
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OSSUtil ossUtil;

    /**
     * 添加任务信息
     * @param taskDTO
     */
    @Override
    public void addTask(TaskDTO taskDTO) {
        //查询当前用户
        // 设置任务所属用户
        Long currentId = BaseContext.getCurrentId();
        //将任务和当前用户绑定
        taskDTO.setUserId(currentId);

        // 业务判断 判断加入之后的文件大小是否没有超出该用户的空间
        Boolean exceed = isExceed(taskDTO.getUserId(), taskDTO.getSize());
        if (exceed) {
            // 用户空间容量不足
            throw new TaskException(MessageConstant.USER_SPACE_IS_EXCEED);
        }
        //可能表示用户没有正确指定要操作的文件，导致任务执行失败或者无效的任务记录插入数据库。
        if (!StringUtils.hasLength(taskDTO.getFilePath())) {
            // 路径为空
            throw new TaskException(MessageConstant.FILE_PATH_IS_NULL);
        }
        taskDTO.setIsFinished(false);
        taskDTO.setIsCancelled(false);
        //判断是否已经存在是未完成且未取消的属性的任务正在执行
        Task taskDB = taskMapper.getByTaskDTO(taskDTO);
        if (taskDB != null) {
            // 任务已提交且正在上传，请勿重复提交
            throw new TaskException(MessageConstant.FILE_SUBMITTED_BUT_NOT_FINISHED);
        }
        // 从前端或其他服务传入的任务数据（通常以 TaskDTO 的形式）转换为数据库实体对象 Task，
        // 表明当前用户已经将该文件上传成功
        Task task = new Task();
        BeanUtils.copyProperties(taskDTO, task);
        taskMapper.insert(task);
    }

    /**
     * 判断用户空间容量是否超过限制
     * @param userId
     * @return
     */
    public Boolean isExceed(Long userId, Double fileSize) {
        //查询用户信息
        User user = userMapper.selectById(userId);
        //查询当前用户的存储总量
        Long userUsedSpace = ossUtil.getUserUsedSpace(user.getBucketName());
        //判断用户空间容量是否超过限制
        return (userUsedSpace + fileSize) > user.getTotalSpace();
    }

    /**
     * 任务上传完毕
     * @param taskDTO
     */
    @Override
    public void finished(TaskDTO taskDTO) {
        //获取当前用户信息
        Long currentId = BaseContext.getCurrentId();
        //将当前用户的文件存入当前的文件中
        taskDTO.setUserId(currentId);
        //设置其文件是没有传输成功的并且是没有取消正在上传的
        taskDTO.setIsFinished(false);
        taskDTO.setIsCancelled(false);
        //查询当前任务的信息
        Task task = taskMapper.getByTaskDTO(taskDTO);
        if (task == null) {
            // 任务不存在
            throw new TaskException(MessageConstant.TASK_NOT_EXIST);
        }
        // 不存在没有没有传输成功的并且是没有取消正在上传的证明已经上传成功
        // 更新finished字段为true
        task.setIsFinished(true);
        task.setUpdateTime(new Date());
        taskMapper.updateById(task);
    }

    /**
     * 获取已完成任务列表
     * @return
     */
    @Override
    public List<FinishedTaskVO> finishedTask() {
        // 获取当前用户id
        Long userId = BaseContext.getCurrentId();
        //查询已经上传成功的文件
        List<Task> taskList = taskMapper.getFinishedByUserId(userId);
        // 处理返回数据中的日期格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd HH:mm");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        // 实体类转换
        List<FinishedTaskVO> taskVOList = new ArrayList<>();
        for (Task task : taskList) {

            String dataFormat = simpleDateFormat.format(task.getCreateTime());
            FinishedTaskVO taskVO = new FinishedTaskVO();
            //将task转化为taskvo为前端展示
            BeanUtils.copyProperties(task, taskVO);
            // 将创建时间字符串存入FinishedTaskVO 对象中
            taskVO.setCreateTimeStr(dataFormat);
            taskVOList.add(taskVO);
        }
        return taskVOList;
    }

    /**
     * 清空上传历史记录
     */
    @Override
    public void clear() {
        //获取当前用户信息
        Long userId = BaseContext.getCurrentId();
        taskMapper.delete(new QueryWrapper<Task>()
                .eq("user_id", userId)
                .eq("is_finished", true)
                .eq("is_cancelled", false));
    }

    /**
     * 取消文件上传
     * @param taskDTO
     */
    @Override
    public void cancelled(TaskDTO taskDTO) {
        //获取用户信息
        Long userId = BaseContext.getCurrentId();

        taskDTO.setUserId(userId);
        taskDTO.setIsFinished(false);
        taskDTO.setIsCancelled(false);
        //查询是否又相同状态的文件，判断是否重复
        Task task = taskMapper.getByTaskDTO(taskDTO);
        if (task == null) {
            // 该上传任务不存在
            throw new TaskException(MessageConstant.TASK_NOT_EXIST);
        }
        task.setIsCancelled(true);
        task.setUpdateTime(new Date());
        taskMapper.updateById(task);
    }
}
